/*
 * gpio_pin.h
 *
 *  Created on: Dec 22, 2018
 *      Author: zhan
 */

#ifndef HARDWARE_GPIO_PIN_H_
#define HARDWARE_GPIO_PIN_H_

#include "stm32f4xx.h"

class GpioPin{
public:
	GPIO_TypeDef *gpiox;
	uint16_t pin;

	GpioPin(GPIO_TypeDef *gpiox, uint16_t pin){
		this->gpiox = gpiox;
		this->pin = pin;
	}

	static uint16_t get_pin_source(uint16_t pin)
	{
		for(int i=0;i<16;i++){
			if ( pin & (1<<i) ){
				return i;
			}
		}
		return 0xFFFF;
	}


	void init(
			GPIOMode_TypeDef mode,
			GPIOSpeed_TypeDef speed,
			GPIOOType_TypeDef output_type,
			GPIOPuPd_TypeDef pull_up_down){
		GPIO_InitTypeDef GPIO_InitStructure;
		GPIO_InitStructure.GPIO_Pin = pin;
		GPIO_InitStructure.GPIO_OType = output_type;
		GPIO_InitStructure.GPIO_Mode = mode;
		GPIO_InitStructure.GPIO_Speed = speed;
		GPIO_InitStructure.GPIO_PuPd = pull_up_down;
		GPIO_Init(gpiox, &GPIO_InitStructure);
	}

	void set_input(
			GPIOPuPd_TypeDef pull_up_down=GPIO_PuPd_UP,
			GPIOSpeed_TypeDef speed=GPIO_Speed_50MHz){
		init(GPIO_Mode_IN, speed, GPIO_OType_OD, pull_up_down);
	}

	void set_output(
			BitAction bit = Bit_SET,
			GPIOOType_TypeDef output_type=GPIO_OType_PP,
			GPIOPuPd_TypeDef pull_up_down=GPIO_PuPd_UP,
			GPIOSpeed_TypeDef speed=GPIO_Speed_50MHz){
		GPIO_WriteBit(gpiox, pin, bit);
		init(GPIO_Mode_OUT, speed, output_type, pull_up_down);
	}

	void write(BitAction bit){
		GPIO_WriteBit(gpiox, pin, bit);
	}

	BitAction read(){
		return GPIO_ReadInputDataBit(gpiox, pin)==0?Bit_RESET:Bit_SET;
	}
};


#endif /* HARDWARE_GPIO_PIN_H_ */
